/* global CLUAS: true */

$(document).ready(function () {
    CLUAS.motion = {};

    var sidebarToggleLines = {
        lines: [],
        push: function (line) {
            this.lines.push(line);
        },
        init: function () {
            this.lines.forEach(function (line) {
                line.init();
            });
        },
        arrow: function () {
            this.lines.forEach(function (line) {
                line.arrow();
            });
        },
        close: function () {
            this.lines.forEach(function (line) {
                line.close();
            });
        }
    };

    function SidebarToggleLine(settings) {
        this.el = $(settings.el);
        this.status = $.extend({}, {
            init: {
                width: '100%',
                opacity: 1,
                left: 0,
                rotateZ: 0,
                top: 0
            }
        }, settings.status);
    }

    SidebarToggleLine.prototype.init = function () {
        this.transform('init');
    };
    SidebarToggleLine.prototype.arrow = function () {
        this.transform('arrow');
    };
    SidebarToggleLine.prototype.close = function () {
        this.transform('close');
    };
    SidebarToggleLine.prototype.transform = function (status) {
        this.el.velocity('stop').velocity(this.status[status]);
    };

    var sidebarToggleLine1st = new SidebarToggleLine({
        el: '.sidebar-toggle-line-first',
        status: {
            arrow: {width: '50%', rotateZ: '-45deg', top: '2px'},
            close: {width: '100%', rotateZ: '-45deg', top: '5px'}
        }
    });
    var sidebarToggleLine2nd = new SidebarToggleLine({
        el: '.sidebar-toggle-line-middle',
        status: {
            arrow: {width: '90%'},
            close: {opacity: 0}
        }
    });
    var sidebarToggleLine3rd = new SidebarToggleLine({
        el: '.sidebar-toggle-line-last',
        status: {
            arrow: {width: '50%', rotateZ: '45deg', top: '-2px'},
            close: {width: '100%', rotateZ: '45deg', top: '-5px'}
        }
    });

    sidebarToggleLines.push(sidebarToggleLine1st);
    sidebarToggleLines.push(sidebarToggleLine2nd);
    sidebarToggleLines.push(sidebarToggleLine3rd);

    var SIDEBAR_WIDTH = '320px';
    var SIDEBAR_DISPLAY_DURATION = 200;

    var sidebarToggleMotion = {
        toggleEl: $('.sidebar-toggle'),
        sidebarEl: $('.sidebar'),
        isSidebarVisible: false,
        init: function () {
            this.toggleEl.on('click', this.clickHandler.bind(this));
            this.toggleEl.on('mouseenter', this.mouseEnterHandler.bind(this));
            this.toggleEl.on('mouseleave', this.mouseLeaveHandler.bind(this));

            $(document)
                .on('sidebar.isShowing', function () {
                    CLUAS.utils.isDesktop() && $('body').velocity('stop').velocity(
                        {paddingRight: SIDEBAR_WIDTH},
                        SIDEBAR_DISPLAY_DURATION
                    );
                })
                .on('sidebar.isHiding', function () {
                });
        },
        clickHandler: function () {
            this.isSidebarVisible ? this.hideSidebar() : this.showSidebar();
            this.isSidebarVisible = !this.isSidebarVisible;
        },
        mouseEnterHandler: function () {
            if (this.isSidebarVisible) {
                return;
            }
            sidebarToggleLines.arrow();
        },
        mouseLeaveHandler: function () {
            if (this.isSidebarVisible) {
                return;
            }
            sidebarToggleLines.init();
        },
        showSidebar: function () {
            var self = this;

            sidebarToggleLines.close();

            this.sidebarEl.velocity('stop').velocity({
                    width: SIDEBAR_WIDTH
                }, {
                    display: 'block',
                    duration: SIDEBAR_DISPLAY_DURATION,
                    begin: function () {
                        $('.sidebar .motion-element').velocity(
                            'transition.slideRightIn',
                            {
                                stagger: 50,
                                drag: true,
                                complete: function () {
                                    self.sidebarEl.trigger('sidebar.motion.complete');
                                }
                            }
                        );
                    },
                    complete: function () {
                        self.sidebarEl.addClass('sidebar-active');
                        self.sidebarEl.trigger('sidebar.didShow');
                    }
                }
            );

            this.sidebarEl.trigger('sidebar.isShowing');
        },
        hideSidebar: function () {
            CLUAS.utils.isDesktop() && $('body').velocity('stop').velocity({paddingRight: 0});
            this.sidebarEl.find('.motion-element').velocity('stop').css('display', 'none');
            this.sidebarEl.velocity('stop').velocity({width: 0}, {display: 'none'});

            sidebarToggleLines.init();

            this.sidebarEl.removeClass('sidebar-active');
            this.sidebarEl.trigger('sidebar.isHiding');

            //在 post 页面下按下隐藏 sidebar 时如果当前选中的是“站点概览”，将 toc 去除 motion 效果
            //防止再次打开时会出现在“站点概览”下的 bug
            if (!!$('.post-toc-wrap')) {
                if ($('.site-overview').css('display') === 'block') {
                    $('.post-toc-wrap').removeClass('motion-element');
                }
            }
        }
    };
    sidebarToggleMotion.init();

    CLUAS.motion.integrator = {
        queue: [],
        cursor: -1,
        add: function (fn) {
            this.queue.push(fn);
            return this;
        },
        next: function () {
            this.cursor++;
            var fn = this.queue[this.cursor];
            $.isFunction(fn) && fn(CLUAS.motion.integrator);
        },
        bootstrap: function () {
            this.next();
        }
    };

    CLUAS.motion.middleWares = {
        logo: function (integrator) {
            var sequence = [];
            var $brand = $('.brand');
            var $title = $('.site-title');
            var $subtitle = $('.site-subtitle');
            var $logoLineTop = $('.logo-line-before i');
            var $logoLineBottom = $('.logo-line-after i');

            $brand.size() > 0 && sequence.push({
                e: $brand,
                p: {opacity: 1},
                o: {duration: 200}
            });

            CLUAS.utils.isMist() && hasElement([$logoLineTop, $logoLineBottom]) &&
            sequence.push(
                getMistLineSettings($logoLineTop, '100%'),
                getMistLineSettings($logoLineBottom, '-100%')
            );

            hasElement($title) && sequence.push({
                e: $title,
                p: {opacity: 1, top: 0},
                o: {duration: 200}
            });

            hasElement($subtitle) && sequence.push({
                e: $subtitle,
                p: {opacity: 1, top: 0},
                o: {duration: 200}
            });

            if (sequence.length > 0) {
                sequence[sequence.length - 1].o.complete = function () {
                    integrator.next();
                };
                $.Velocity.RunSequence(sequence);
            } else {
                integrator.next();
            }


            function getMistLineSettings(element, translateX) {
                return {
                    e: $(element),
                    p: {translateX: translateX},
                    o: {
                        duration: 500,
                        sequenceQueue: false
                    }
                };
            }

            /**
             * Check if $elements exist.
             * @param {jQuery|Array} $elements
             * @returns {boolean}
             */
            function hasElement($elements) {
                $elements = Array.isArray($elements) ? $elements : [$elements];
                return $elements.every(function ($element) {
                    return $.isFunction($element.size) && $element.size() > 0;
                });
            }
        },

        menu: function (integrator) {
            $('.menu-item').velocity('transition.slideDownIn', {
                display: null,
                duration: 200,
                complete: function () {
                    integrator.next();
                }
            });
        },

        postList: function (integrator) {
            var $post = $('.post');
            var hasPost = $post.size() > 0;

            hasPost ? postMotion() : integrator.next();

            function postMotion() {
                var postMotionOptions = window.postMotionOptions || {
                    stagger: 100,
                    drag: true
                };
                postMotionOptions.complete = function () {
                    integrator.next();
                };

                $post.velocity('transition.slideDownIn', postMotionOptions);
            }
        },

        sidebar: function (integrator) {
            if (CONFIG.sidebar.display === 'always') {
                CLUAS.utils.displaySidebar();
            }
            integrator.next();
        }
    };

});
